/*
	This script file is part of the Sonic 3 A.I.R. script software distribution.
	Copyright (C) 2017-2024 by Eukaryot

	Published under the GNU GPLv3 open source software license, see license.txt
	or https://www.gnu.org/licenses/gpl-3.0.en.html
*/



//# address-hook(0x03bf56) end(0x03bf62)
function void fn03bf56()
{
	u16[A0 + 0x36] = objA0.subtype2c * 8
	objA0.update_address = 0x03bf68
	fn03bf68()
}


//# address-hook(0x03bf68) end(0x03bf9a)
function void fn03bf68()
{
	A2 = A0 + 0x30
	A1 = 0xffffb000
	D1.u16 = control.player1
	fn03bfa0()

	++A2
	A1 = 0xffffb04a
	D1.u16 = control.tails
	fn03bfa0()

	if (u8[A0 + 0x30] != 0)
	{
		camera.use_forced_target = true
		camera.forced_target.x = objA0.position.x.u16
		camera.forced_target.y = u16[0xffffb000 + 0x14]
	}

#if STANDALONE
	bool player2attached = u8[A0 + 0x31]
	CheckForUnloadObject()

	// Handle second character if he's still attached to the pole
	if (objA0.update_address == 0 && player2attached)
	{
		u8[0xffffb04a + 0x2e] &= ~(control_flag.DISABLE_ANIMATION | control_flag.DISABLE_UPDATE)
	}
#else
	CheckForUnloadObject()
#endif
}


//# address-hook(0x03bfa0) end(0x03bffc)
function void fn03bfa0()
{
	if (u8[A2] == 0)
	{
		fn03c0d0()
		return
	}

	if (debug_mode.state != 0 || u8[A1 + 0x05] >= 0x04 || s8[A1 + 0x2e] < 0)
	{
		fn03c096()
		return
	}

	if (D1 & 0x0100)	// CONTROL_UP held
	{
		D0.u16 = objA0.position.y.u16 - u16[A0 + 0x36]
		if (D0.s16 < s16[A1 + 0x14])
		{
			--objA1.position.y.u16
		}
	}
	if (D1 & 0x0200)	// CONTROL_DOWN held
	{
		D0.u16 = objA0.position.y.u16
		if (D0.s16 > s16[A1 + 0x14])
		{
			++objA1.position.y.u16
		}
	}

	// Check if jump button pressed
	if (D1.u16 & CONTROL_ABC)
	{
		fn03c068()
	}
	else
	{
		u8[A2 + 0x04] += 8
		fn03c010()
		fn03bffe()
	}
}


//# address-hook(0x03bffe) end(0x03c00e)
function void fn03bffe()
{
	D0 = objA1.animation.sprite
	u32 backupA2 = A2
	SetCharacterSpritePatterns()
	A2 = backupA2
}


//# address-hook(0x03c010) end(0x03c046)
function void fn03c010()
{
	D0 = u8[A2 + 0x04]
	if (D0.s8 >= 0)
		objA1.sprite_attributes |= sprite_attribute.PRIORITY
	else
		objA1.sprite_attributes &= ~sprite_attribute.PRIORITY

	D0.u8 >>= 4
	D1.u8 = u8[0x03c048 + D0.u16]		// Set player character's pole spinning sprite
	u8[A1 + 0x22] = D1.u8
	D1.s16 = s8[0x03c058 + D0.u16]
	if (objA1.render_flags & render_flag.FLIP_X)
	{
		D1.s16 = -D1.s16
	}
	D1.u16 += objA0.position.x.u16
	objA1.position.x.u16 = D1.u16
}


//# address-hook(0x03c068) end(0x03c090)
function void fn03c068()
{
	objA1.velocity.x = (D1 & 0x0400) ? -0x1000 : 0x1000		// CONTROL_LEFT held
	objA1.velocity.y = -0x100
	objA1.hitbox_extends.y = char.hitbox.y.ROLLING
	objA1.hitbox_extends.x = char.hitbox.x.ROLLING
	objA1.state = char.state.ROLLING
	objA1.flags2a |= char.flag.ROLLING

	fn03c096()
}


//# address-hook(0x03c096) end(0x03c0ce)
function void fn03c096()
{
	u8[A2] = 0
	u8[A2 + 0x02] = 0x1e

	objA1.sprite_attributes &= ~sprite_attribute.PRIORITY
	u8[A1 + 0x27] = 0
	objA1.flags2a |= char.flag.IN_AIR
	objA1.flags2a &= ~char.flag.CONTROL_LOCK
	u8[A1 + 0x2e] &= ~(control_flag.DISABLE_ANIMATION | control_flag.DISABLE_UPDATE)
	u8[A1 + 0x2f] = 0
	u8[A1 + 0x3d] = 0
	u8[A1 + 0x40] = 1
}


//# address-hook(0x03c0d0) end(0x03c19a)
function void fn03c0d0()
{
	if (u8[A2 + 0x02] != 0)
	{
		--u8[A2 + 0x02]
		return
	}

	D0.u16 = objA1.position.x.u16 - objA0.position.x.u16 + 0x0c
	if (D0.u16 < 0x18)
	{
		D1.u16 = u16[A0 + 0x36]
		D0.u16 = objA0.position.y.u16 - objA1.position.y.u16 + 0x10
		if (D0.u16 < u16[A0 + 0x36] && debug_mode.state == 0 && u8[A1 + 0x05] < 0x04 && u8[A1 + 0x2e] == 0)
		{
			objA1.velocity.x = 0
			objA1.velocity.y = 0
			objA1.groundspeed = 0
			objA1.render_flags &= ~(render_flag.FLIP_X | render_flag.FLIP_Y)
			D0.u8 = u8[A1 + 0x1e]
			u8[A1 + 0x1e] = u8[A1 + 0x44]
			u8[A1 + 0x1f] = u8[A1 + 0x45]

			if (u8[A1 + 0x2a] & char.flag.ROLLING)
			{
				objA1.flags2a &= ~char.flag.ROLLING
				D0.s8 -= u8[A1 + 0x44]
				objA1.position.y.u16 += D0.s8
			}

			objA1.position.x.u16 = objA0.position.x.u16
			D0.u16 = objA0.position.y.u16
			if (D0.u16 < objA1.position.y.u16)
			{
				objA1.position.y.u16 = D0.u16
			}

			objA1.render_flags &= ~render_flag.FLIP_Y
			u8[A1 + 0x20] = 0
			objA1.flags2a |= char.flag.IN_AIR
			objA1.flags2a &= ~char.flag.FACING_LEFT
			u8[A1 + 0x2e] = (control_flag.DISABLE_ANIMATION | control_flag.DISABLE_UPDATE)

			u8[A2 + 0x04] = 0xe0
			u8[A2] = 1

			fn03c010()
			fn03bffe()
		}
	}
}



//-------------------------------------------------------//
// Top of propeller                                      //
//-------------------------------------------------------//

//# address-hook(0x03c1a6) end(0x03c1e8)
function void fn03c1a6()
{
	objA0.mapping_offset = 0x03c20c
	objA0.sprite_attributes = (sprite_attribute.PALETTE.LINE1 | 0x02e5)
	objA0.render_flags |= render_flag.WORLD
	objA0.box_size.x = 0x68
	objA0.box_size.y = 0x08
	objA0.sprite_priority = 0x0280
	objA0.render_flags |= render_flag.COMPOUND
	objA0.compound.count = 0x01

	A2 = A0 + 0x18
	u16[(A2+=2)-2] = objA0.position.x.u16
	u16[(A2+=2)-2] = objA0.position.y.u16
	u16[(A2+=2)-2] = 0

	objA0.update_address = 0x03c1ee
	fn03c1ee()
}


//# address-hook(0x03c1ee) end(0x03c202)
function void fn03c1ee()
{
	A2 = A0 + 0x1d
	u8[A2] = (u8[A2] + 1) % 4
	objA0.collision_attributes = u8[0x03c208 + u8[A2]]
	fn01b662()
}
